<?PHP

class menuBase
{
    private $title = "";
    private $prompt = "";
    private $quitmes = "";
    private $quit = TRUE;
    private $itemNum = 0;
    private $item = array();

    public function __construct($arg = array())
    {
        if (isset($arg['title']))
            $this->title = $arg['title'];

        if (isset($arg['prompt'])) {
            if ($arg['prompt'] == "")
                $arg['prompt'] = "请输入";
            $this->prompt = $arg['prompt'];
        }

        if (isset($arg['quitmes']))
            $this->quitmes = $arg['quitmes'];

        $this->itemNum = 0;
    }

    public function menuQuit()
    {
        $this->quit = FALSE;
    }

    public function addItem(string $name, $call = "", $usrArg = array())
    {
        $this->item[$this->itemNum]['name'] = $name;
        $this->item[$this->itemNum]['call'] = $call;
        $this->item[$this->itemNum]['arg'] = $usrArg;
        $this->itemNum++;
    }

    public function editItem(int $index = -1, string $name = "", $call = "", $usrArg = array())
    {
        if ($index <= 0 || $index > $this->itemNum)
            return;

        $index--;

        if ($name != "")
            $this->item[$index]['name'] = $name;
        if ($call != "")
            $this->item[$index]['call'] = $call;
        if (count($usrArg) != 0)
            $this->item[$index]['arg'] = $usrArg;
    }

    public function delItem(int $index = -1)
    {
        if ($index <= 0 || $index > $this->itemNum)
            return;
        unset($this->item[--$index]);
    }

    static private function showMenu($menu)
    {
        if ($menu->title != "")
            echo $menu->title, PHP_EOL;

        foreach ($menu->item as $item)
        {
            echo $item['name'], PHP_EOL;
        }
        echo $menu->quitmes, PHP_EOL;
        printf("%s[1 - %d]: ", $menu->prompt, $menu->itemNum + 1);
    }

    static public function getInput($start = 3, $end = 20, $show, ...$show_data)
    {
        if ($start > $end)
        {
            $start ^= $end;
            $end ^= $start;
            $start ^= $end;
        }
        // var_dump($show_arg);
        while (TRUE) {
            if ($show == null)
                echo "请输入[$start - $end]: ";
            else {
                if (count($show_data) == 0)
                    call_user_func($show);
                else
                    call_user_func($show, ...$show_data);
            }
            if (fscanf(STDIN, "%d", $n) < 1 || $n < $start || $n > $end)
                continue;
            break;
        }

        return $n;
    }

    public function getMenuInput()
    {
        $show = array("menu", "showMenu");
        $arg = array($this);

        return self::getInput(1, $this->itemNum + 1, $show, ...$arg) - 1;
    }

    public function run($n)
    {
        if ($n == $this->itemNum ||
           call_user_func($this->item[$n]['call'],
                            $n, $this->item[$n]['arg']))
            return TRUE;
        return FALSE;
    }

    public function show()
    {
        if ($this->quitmes == "")
            $this->quitmes = ($this->itemNum + 1).". 退出";

        while ($this->quit)
        {
            $n = $this->getMenuInput();
            if ($this->run($n))
                break;
        }
    }
}
